from datetime import datetime
from typing import List

from sqlalchemy import DateTime, Enum, ForeignKey, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship

from ._ai_model_ import AIModel
from ._basic_ import BasicModel
from ._secondary_tables_ import (
    chat_room_user_association, conversation_ai_model_association, conversation_user_association,
)
from ._user_ import User


class Speaker(Enum):
    """
    发言者
    """
    SYSTEM = "system"
    USER = "user"
    AI = "AI"
    FUNCTION = "function"


class ChatRoom(BasicModel):
    """
    聊天室
    """
    __tablename__ = "chat_rooms"

    name: Mapped[str] = mapped_column(String(255), unique=True, index=True, nullable=False, comment='聊天室名称')
    """
    聊天室名称
    用于前端展示
    """
    users = relationship('User', secondary=chat_room_user_association, back_populates='chat_rooms')


class Conversation(BasicModel):
    """
    对话
    """
    __tablename__ = 'conversations'

    primary_model: Mapped[AIModel] = relationship('AIModel')
    """
    主要 AI 模型
    """
    primary_model_id: Mapped[int] = mapped_column(Integer, ForeignKey('ai_models.id'), comment='主要 AI 模型 ID')
    """
    主要 AI 模型 ID
    表示后续对话将采用那个 AI 模型，除非用户切换 AI 模型，否则后续对话内容都将视为与该 AI 模型进行的对话
    """

    topic: Mapped[str] = mapped_column(String(255), index=True, nullable=False, comment='对话主题')
    """
    对话主题
    用于呈现给用户的对话标题
    """
    summary: Mapped[str] = mapped_column(Text, nullable=False, default='', comment='对话总结')
    """
    对话总结
    将作为 AI 接口中的历史对话内容
    """

    users: Mapped[List[User]] = relationship(
        'User',
        secondary=conversation_user_association,
        back_populates='conversations',
    )
    """
    关联的用户列表
    """
    ai_models: Mapped[List[AIModel]] = relationship(
        'AIModel',
        secondary=conversation_ai_model_association,
        back_populates='conversations',
    )
    """
    关联的 AI 模型列表
    """
    messages: 'Mapped[List[Message]]' = relationship('Message', back_populates='conversation')
    """
    关联的消息列表
    """


class Message(BasicModel):
    """
    消息
    """
    __tablename__ = 'messages'

    conversation_id: Mapped[int] = mapped_column(Integer, ForeignKey('conversations.id'))
    user_id: Mapped[int] = mapped_column(Integer, ForeignKey('users.id'))
    ai_model_id: Mapped[int] = mapped_column(Integer, ForeignKey('ai_models.id'))
    content: Mapped[str] = mapped_column(Text)
    timestamp = mapped_column(DateTime, default=datetime.utcnow)
    speaker: Mapped[Speaker] = mapped_column(Speaker)

    conversation: Mapped[Conversation] = relationship('Conversation', back_populates='messages')
